# -*- coding:utf-8 -*-

'''
JOAQUÍN RAMÓN ANTÚNEZ SÁNCHEZ - 11 de septiembre de 2014
'''

from datetime import date
from mon.mon import monsql, monstr

class mezzo(object):
    
    def __init__(self, arg = None):
        self.__id = 0
        
        ''' datos -----------------------------------------------------------------------'''
        tbl = type(self).__name__
        if tbl in 'cd':
            self.__data = {'titulo' : '', 'titulo_interpretacion': '', 'volumenes' : 0,
                           'id_etiqueta' : 0, 'coleccion' : '', 'numero_de_serie' : '',
                           'edicion' : 0, 'horas' : 0, 'minutos' : 0, 'segundos': 0,
                           'generos' : 0}
        elif tbl in 'bach':
            self.__data = {'apellidos':'', 'nombre':'', 'nacimiento': 0, 'muerte' : 0}
        elif tbl in 'kleiber':
            self.__data = {'apellidos' : '', 'nombre' : ''}
        elif tbl in 'fca':
            self.__data = {'nombre' : '', 'articulo' : ''}
        elif tbl in 'decca':
            self.__data = {'etiqueta': ''}
            
        ''' buscar o asignar -----------------------------------------------------------'''
        if arg:
            if type(arg) is dict:
                self.assign(arg)
            else:
                self.find(arg)         
                                            
    
    def __tabla(self):
        '''Determinar la tabla en función de la clase del objeto'''
        s = type(self).__name__
        if   s in 'cd':         return 'discos'
        elif s in 'bach':       return 'compositores'
        elif s in 'kleiber':    return 'artistas'
        elif s in 'fca':        return 'orquestas'
        elif s in 'decca':      return 'discograficas'
        
    def __buscar_en_campo(self):
        ''' determino el campo de búsqueda según la tabla implícita en el objeto de la clase'''
        tbl = type(self).__name__
        if   tbl in 'cd': return 'numero_de_serie'
        elif tbl in ['bach', 'kleiber'] : return 'CONCAT_WS(" ", nombre, apellidos)'
        elif tbl in 'fca': return (
                                   'IF(articulo is null or articulo = "", nombre, '
                                   'CONCAT_WS(" ", articulo, nombre))' 
                                   )
        elif tbl in 'decca': return 'etiqueta'
        
    def __sin_comas(self, txt):
        '''método interno que elimina la coma simple o la doble de una cadena
        obtenida de los valores o claves de un diccionario'''
        while txt.find('\'') != -1:
            txt = txt.replace('\'', '')        
            #txt = txt.replace('\"', '')
        return txt
        
    def add(self):
        try:
            if self.__id != 0: raise Exception('El registro ya está guardado')            
            db = monsql()
            id = db.inc( self.__tabla() )
            if id == 0: raise Exception('No se ha podido obtener el incremento numérico para el nuevo registro.')
            
            values = ''
            keys = ''
            for key, value in self.__data.items():                
                if not str(value).isdigit():
                    value = '"{}"'.format(  value )
                values += '{}, '.format(value)
                keys += '{}, '.format(key)     
                
            
            query = 'INSERT INTO %s\n(%s id)\nVALUES(%s %d)' % (self.__tabla(), keys, values, int(id))
                        
            result = db.execute(query)
            if result == 1: self.__id = id
            return result
            
        except Exception as ex:
            print ex.message
            return 0                     
    
    def update(self):
        try:
            if self.__id == 0: 
                raise Exception('No se pueden guardar los cambios de un registro inexistente')
            
            query = 'UPDATE {}\nSET '.format(self.__tabla())
            for key, value in self.__data.items():
                if not str(value).isdigit():
                    value = '"{}"'.format(value)
                query += '{} = {},\n'.format(key, value)                
            
            query += 'modificado = CURDATE()\n'
            query += 'WHERE id = {}'.format(self.__id)
            
            return monsql().execute(query) 
                    
        except Exception as ex:
            print ex.message
            return 0    
    
    def remove(self):
        pass
        
      
    def find(self, arg):
        query = str(self.__data.keys())
        query = 'SELECT id, {}\nFROM {}\n'.format( self.__sin_comas(query[1 : len(query) -1]), self.__tabla() )
        if type(arg) is int:
            query = '{}where id = {}'.format(query, arg)
        else:    
            query = '{}where {} = "{}"'.format( query, self.__buscar_en_campo(), arg )
        
        self.clear()
        row = monsql().execute(query)
        self.assign(row) 
    
    def assign(self, row):
        '''Obtiene el valor de los campos del objeto de la fila de una consulta'''
        if row and row['id']:
            self.__id = row['id']
            for key in self.__data.keys():
                self.__data[key] = row[key]
            
            
    def clear(self):
        for key in self.__data.keys():
            if type(self.__data[key]) is int:
                self.__data[key] = 0
            else:
                self.__data[key] = ''                
        self.__id = 0                
        
        
    ''' PROPIEDADES -------------------------------------------------------------- '''
    def __get_id(self): return self.__id
    
    id  = property(__get_id)
    
    
    
########################################################################################
# Tempo
########################################################################################    
class Tempo(object):
    ''' clase para al conversión de la duración del cd, según los siguientes formatos de entrada:
    h.mm:ss
    mm:ss
    minutos totales
    La salida es una cadena vacía si no se ha facilitado la duración total o se ha producido algún error;
    en caso contrario, h.mm:ss
    '''
    def __init__(self, value):
        self.__horas    = 0
        self.__minutos  = 0
        self.__segundos = 0
        
        value = str(value).strip()
        if len(value) == 3 or len(value) == 2:
            self.__tempo_corto(value)
        elif len( value ) == 5: self.__tempo_medio(value)
        elif len( value ) == 7 or len( value ) == 8: self.__tempo_largo(value)    
          
    
    def __tempo_corto(self, value):        
        if str(value).isdigit():
            value = int(value)
            '''
            while value >= 60:
                self.__horas += 1
                value -= 60                
            self.__minutos = value
            '''
            self.__horas    = value / 60
            self.__minutos  = value % 60 
            
            return True
        else:
            return False
            
    def __tempo_medio(self, value):
        '''mm:ss'''            
        if not value[2] == ':': return False
        
        m = value[0 : 2]
        s = value[3 : 5]
        
        if not str(m).isdigit() or not str(s).isdigit(): return False
        m = int(m)
        s = int(s)
        if m < 0 or s < 0:  return False
        
        # si doy valor >= 60, ajusto
        #if m >= 60 or s >= 60: return False
        if m >= 60:
            self.__horas += ( m / 60 )
            m = ( m % 60 )
        if s >= 60:
            m += ( s / 60 )
            s = ( s % 60 )    
        
        self.__minutos = m
        self.__segundos = s
        
        return True
    
    def __tempo_largo(self, value):
        ''' h.mm:ss'''
        # busco el punto
        pos = str( value ).find('.') 
        if pos == -1: return False
        if len(value) == 7 and not pos == 1: return False
        if len(value) == 8 and not pos == 2: return False
        
        # extraer las horas
        h = value[0 : pos]
        if not str(h).isdigit(): return False        
        if h <= 0:  return False # no admito "0.23:14"
        
        # compruebo que minutos y segundos sean correctos
        value = value[ pos + 1 : len(value) ]
        if self.__tempo_medio( value ):
            self.__horas = h
            return True
        else:
            return False
        
        
        # métodos para extraer las propiedades
    def __get_horas(self):      return self.__horas    
    def __get_minutos(self):    return self.__minutos
    def __get_segundos(self):   return self.__segundos
    
    # propedades
    horas       = property( __get_horas )
    minutos     = property( __get_minutos )
    segundos    = property( __get_segundos )    